﻿@using Resource;
@{
    Layout = null;
}
<!DOCTYPE html>

<html>
<head>
    <meta name="viewport" content="width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=no" />
    <meta http-equiv="Expires" content="0">
    <meta http-equiv="Pragma" content="no-cache">
    <meta http-equiv="Cache-control" content="no-cache">
    <meta http-equiv="Cache" content="no-cache">
    @{ await Html.RenderPartialAsync("/Views/Shared/_LayoutScript.cshtml"); }
    @{ await Html.RenderPartialAsync("/Views/Shared/_StyleCss.cshtml"); }
    @*<!-- 引入 xlsx 库<script src="https://cdn.bootcdn.net/ajax/libs/xlsx/0.18.5/xlsx.full.min.js"></script>-->*@
    @*<script src="/lib/xlsx/xlsx.full.min.js?v=@DateTime.Now.Ticks"></script>*@

    <link href="/css/DeviceAssemblyYield.css?v=@DateTime.Now.Ticks" rel="stylesheet" />
    <title>DeviceAssemblyYield</title>
    <style type="text/css">
        /*报表样式*/
        html, body {
            background: url(../images/ProcessCapacity/bgwhite.png) no-repeat;
            background-size: cover;
            font-size: .16rem;
            color: #ffffff;
            position: relative;
            width: 100%;
            height: 100%;
            font-family: myFirstFont !important;
            color: black;
        }

        .hover-image {
            display: none;
            position: absolute;
            top: 20px;
            left: 0;
            width: 35vw;
            border: 1px solid #ccc;
            background: #fff;
            z-index: 999;
        }

        .warn-flag:hover .hover-image {
            display: block;
        }

        #board {
            padding: 0.0rem 0.1rem;
        }

        .rightTop {
            background-color: #f7fdff;
        }

        .dropbtn, button {
            background-color: #0aa9cd;
        }

        #query > button {
            background-color: #0aa9cd;
            border: 2px solid #0aa9cd;
        }

        .dropdown-content {
            background-color: #12bed0;
        }

        .ZebraNo {
            background-color: #e8f1f9;
        }

        .ZebraTo {
            background-color: #ffffff;
        }

        .note {
            color: red;
            font-size: 0.15rem;
            font-weight: bolder;
        }

        .table-title {
            color: #19adcf;
            font-size: 0.15rem;
            font-weight: bolder;
        }

        .process:hover {
            background-color: #b3f1fe;
        }

        #myTable{
            border-collapse: collapse;
        }

        #myTable td {
            border: 1px solid #cecece;
        }
        /*END*/

        .truncate {
            text-align: center;
            max-width: 1.2rem;
            white-space: nowrap;
            overflow: hidden;
            text-overflow: ellipsis;
        }
        /*明细模态*/
        .show_mode {
            border-radius: 0.1rem;
            position: absolute;
            z-index: 99;
            height: 10.6rem;
            width: 100%;
            /*text-align: center;*/
            background: #a2c2e2;
            display: none;
        }

        .show_mode > .contentdetail > div {
            color: black;
            height: 33.3%;
            width: 50%;
            float: left;
            border-block: solid #ffffff 1px;
        }

        .show_mode > .contentdetail > div > label {
            color: black;
        }

        .detail {
            color: black;
            height: 3rem;
            width: 100%;
            /*background-color: #dfe4ee;*/
        }

        .mode_close {
            float: right;
        }

        .mode_close:hover {
            background-color: #848690;
        }
        /*end*/
        #btn_export {
            height: 0.3rem;
            font-size: 0.16rem;
            margin-left: 2px;
            border-radius: 2px;
            background-color: #e9e9ed;
            border: 1px solid #8f8f9d;
        }

        #btn_export:hover {
            background-color: #dddddd;
        }
    </style>
</head>
<body class="fill-parent" style="overflow-y: hidden; color: black;">
    <div class="main">
        <div class="header">
            <div class="header-left fl">
                <img src="/images/logo.png?v=@DateTime.Now.Ticks" class="scaled-image" draggable="false" oncontextmenu="return false;" ondragstart="return false;" />
            </div>
            <div class="btn">
                <spn>
                    <div id="query">
                        <div class="dropdown">
                            <button class="dropbtn">@Label.Desktop</button>
                            <div class="dropdown-content">
                                <a class="menudropdown" href=@Html.Raw($"https://dashboard.li.lumentuminc.net/API/DesktopApp/Dashboard.exe?v={DateTime.Now.Ticks}") download>@Label.Local</a>
                                <a class="menudropdown" href=@Html.Raw($"https://dashboard.li.lumentuminc.net/API/DesktopApp/Dashboard_lnk.zip?v={DateTime.Now.Ticks}") download>@Label.Shortcut</a>
                            </div>
                        </div>
                        <div class="dropdown">
                            <button class="dropbtn">@Label.Data@Label.Datum</button>
                            <div class="dropdown-content">
                                <a class="menudropdown" onclick="DeviceAssemblyExport('DeviceAssemblyYield')">@Label.Report@Label.Export</a>
                            </div>
                        </div>
                        <div class="dropdown">
                            <button class="dropbtn">@Label.Language</button>
                            <div class="dropdown-content">
                                <a class="menudropdown" onclick="setLanguageCookie('@Const.CNLANGUAGE')">@Label.Chinese</a>
                                <a class="menudropdown" onclick="setLanguageCookie('@Const.USLANGUAGE')">@Label.English</a>
                            </div>
                        </div>
                        <button class="modalBtn dimension">@Label.Full</button>
                    </div>
                </spn>
            </div>
            <div class="header-center fl">
                <div class="header-title"></div>
                <div class="header-img"></div>
            </div>
            <div class="header-right fl" id="time"></div>
            <div class="header-bottom fl"></div>
        </div>
        <div class="center">
            <div class="center-left fl">
                <div class="left-top rightTop border">
                    <div class="title note">
                        <span class="warn-flag" style="color:red; position: relative;">ℹ️<img src="../images/lot.png?v=@DateTime.Now.Ticks" class="hover-image" /></span>
                        @Label.Note_DeviceAssemblyYield
                    </div>
                    <div id="board">
                        <div class="query">
                            <input type="datetime-local" id="startdate" name="startdate" placeholder="@Label.Start@Label.Time" style="width:1.9rem">
                            <span class="exampleInputProject tle">@Label.To</span>
                            <input type="datetime-local" id="enddate" name="enddate" placeholder="@Label.Start@Label.End" style="width:1.9rem">
                            <select id="cmb_prod_type" name="ProdType" placeholder="select prodtype">
                                <option value="ALL">@Label.ALL</option>
                                <option value="Normal">@Label.Fresh</option>
                                <option value="Rework">@Label.Rework</option>
                                <option value="RMA">@Label.RMA</option>
                            </select>
                            <select id="cmb_proj_code" placeholder="select ProjCode">
                                <option value="ALL" selected>@Label.ALL</option>
                                <option value="">@Label.PleaseSelect</option>
                            </select>
                            <select id="cmb_process" placeholder="select Process">
                                <option value="ALL" selected>@Label.ALL</option>
                                <option value="">@Label.PleaseSelect</option>
                            </select>
                            <button id="btn_query" class="btn btn-primary  btn-sm col-md-12" type="button" onclick="Getdata()">@Label.Query</button>
                        </div>
                        <div id="table-container">
                            <div id="left-table" class="rightTop">
                                <div class="tab tab-table">
                                    <button class="tablinks active" onclick="OpenTab(event,'tab-table','left-table-body',ProcessYieldBoard)">AAProcessYield</button>
                                    <button class="tablinks" onclick="OpenTab(event,'tab-table','left-table-body',TesterFailBoard)">TesterFailYield</button>
                                </div>
                                <div id="left-table-body"></div>
                            </div>
                            <div id="right-table">
                                <div id="process_container" class="rightTop">
                                    <div class="tab tab-chart">
                                        <button class="tablinks active" onclick="OpenTab(event,'tab-chart','process_yield',ProcessYieldChartFun)">Process&nbsp;Yield&nbsp;Chart</button>
                                        <button class="tablinks" onclick="OpenTab(event,'tab-chart','failure_mode',FailureModeAreaChartFun)">FailureMode&nbsp;Rate&nbsp;Chart</button>
                                        <button class="tablinks" onclick="OpenTab(event,'tab-chart','tester_yield',TesterYieldFailureModeChartFun)">Tester&nbsp;Yield&nbsp;FailureMode&nbsp;Chart</button>
                                        <div id="cmb_type" style="float: right; line-height: 0.5rem;">
                                            <select id="cmb_data_type">
                                                <option value="DAY">天</option>
                                                <option value="WEEK">周</option>
                                            </select>
                                            <select id="cmb_yield_type">
                                                <option value="prime_yield">PrimeYield</option>
                                                <option value="final_yield">FinalYield</option>
                                            </select>
                                            <select id="cmb_tester_type"></select>
                                        </div>
                                        <div class="search" style="float: right; line-height: 0.5rem;">
                                            <input list="process_search" id="process_input" name="search" placeholder="请输入Process...">
                                            <datalist id="process_search" class="process_search" style="height: calc(4.7rem - 0.12rem);"></datalist>
                                        </div>
                                    </div>
                                    <div id="process_yield" class="detail"></div>
                                </div>
                                <div id="failuremode" class="rightTop">
                                    <div id="failuremode_pareto" class="detail"></div>
                                </div>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        </div>
        <div class="show_mode">
            <div style="width:100%; height:0.3rem;">
                <div class="mode_close" style="height:100%;margin-right:10px;line-height:0.3rem;"><label style="font-size:0.17rem;color:white;">关闭&times;</label></div>
            </div>
            <div class="contentdetail"></div>
        </div>
    </div>

    <script type="text/javascript" href="?v=@DateTime.Now.Ticks">
        $(".show_mode,#cmb_tester_type").css("display", "none");
        $('.mode_close').click(function () {
            $(".show_mode").css("display", "none");
            $(".contentdetail").empty();
            $(".contentdetail div").remove();
        });
        $(document).ready(function () {
            var whei = $(window).height();
            $("html").css({ fontSize: whei / 12.5 });
            $(window).resize(function () {
                if ($(".dimension").text() == "@Html.Raw(Label.Full)") {
                    var whei = $(window).height();
                    $("html").css({ fontSize: whei / 12.5 });
                }
                else {
                    var whei = $(window).width();
                    $("html").css({ fontSize: whei / 22 })
                }
                echartsautomatic();
            });
            function numberToUpperCase(number) {
                var uppercaseMonths = [
                    '一月', '二月', '三月', '四月', '五月', '六月',
                    '七月', '八月', '九月', '十月', '十一月', '十二月'
                ];
                return uppercaseMonths[number - 1];
            }
            var myDate = new Date();
            var result = numberToUpperCase(myDate.getMonth() + 1);
            $('.header-title').html("@Html.Raw(Label.Board_DeviceAssemblyYield)");
            function getTime() {
                var myDate = new Date();
                var myYear = myDate.getFullYear();
                var myMonth = myDate.getMonth() + 1;
                var myToday = myDate.getDate();
                var myDay = myDate.getDay();
                var myHour = myDate.getHours();
                var myMinute = myDate.getMinutes();
                var mySecond = myDate.getSeconds();
                var week = ['@Label.Sunday', '@Label.Monday', '@Label.Tuesday', '@Label.Wednesday', '@Label.Thursday', '@Label.Friday', '@Label.Saturday'];
                var nowTime;

                nowTime = myYear + '-' + fillZero(myMonth) + '-' + fillZero(myToday) + '&nbsp;&nbsp;' + fillZero(myHour) + ':' + fillZero(myMinute) + ':' + fillZero(mySecond) + '&nbsp;&nbsp;' + week[myDay] + '&nbsp;&nbsp;';
                $('#time').html(nowTime);
            };
            function fillZero(str) {
                var realNum;
                if (str < 10) {
                    realNum = '0' + str;
                } else {
                    realNum = str;
                }
                return realNum;
            }
            setInterval(getTime, 1000);
            $('.dimension').on('click', function (e) {
                var element = document.documentElement;
                if ($(".dimension").text() == "@Html.Raw(Label.Full)") {
                    if (element.requestFullscreen) {
                        element.requestFullscreen();
                    } else if (element.mozRequestFullScreen) {
                        element.mozRequestFullScreen();
                    } else if (element.webkitRequestFullscreen) {
                        element.webkitRequestFullscreen();
                    } else if (element.msRequestFullscreen) {
                        element.msRequestFullscreen();
                    }
                    $(".dimension").text("@Html.Raw(Label.Exit+Label.Full)");
                } else {
                    if (document.exitFullscreen) {
                        document.exitFullscreen();
                    } else if (document.mozCancelFullScreen) {
                        document.mozCancelFullScreen();
                    } else if (document.webkitCancelFullScreen) {
                        document.webkitCancelFullScreen();
                    } else if (document.msExitFullscreen) {
                        document.msExitFullscreen();
                    }
                    $(".dimension").text("@Html.Raw(Label.Full)");
                }
            });

            $('#btn_query').prop('disabled', true);
            $('#startdate').on('change', function () {
                var startDate = new Date($(this).val());
                var endDate = new Date($('#enddate').val());
                startDate.setDate(startDate.getDate() + 1);
                var minEndDate = startDate.toISOString().split('T')[0];
                $('#enddate').attr('min', minEndDate);
                if (endDate < startDate) {
                    $('#enddate').val($(this).val());
                }
            });
            $('#enddate').on('change', function () {
                var startDate = new Date($('#startdate').val());
                var endDate = new Date($(this).val());
                endDate.setDate(endDate.getDate() - 1);
                var maxStartDate = endDate.toISOString().split('T')[0];
                $('#startdate').attr('max', maxStartDate);
                if (startDate > endDate) {
                    $('#startdate').val($(this).val());
                }
            });
        });

        //图表自适应大小
        var chartIds = ['process_yield', 'failuremode_pareto'];
        function echartsautomatic() {
            var charts = [];
            chartIds.forEach(function (chartId) {
                var chart = echarts.init(document.getElementById(chartId));
                charts.push(chart);
            });
            window.onresize = function () {
                charts.forEach(function (chart) {
                    chart.resize();
                });
            };
        }

        //定时查询
        var Tabtimer;
        function TabInterval() {
            clearInterval(Tabtimer);
            //每隔10m执行一次
            Tabtimer = setInterval(function () {
                var endDate = new Date($("#enddate").val());
                if (endDate > new Date()) {
                    getdate();
                }
            }, 10 * 60 * 1000);
        }

        var select_dt;
        var ComboxAction = function () {
            var projectsele = $("#cmb_proj_code");
            var process = $("#cmb_process");
            loadData(projectsele, api + '/ReportAction/GetDeviceAssemblyYieldProcess', false);
            projectsele.change(function () {
                var uniqueProcess = select_dt
                    .filter(item => item.PROJ_CODE === $(this).val())
                    .reduce((acc, { PROCESS_ID }) => {
                        if (!acc.some(e => e.value === PROCESS_ID)) {
                            acc.push({ value: PROCESS_ID, text: PROCESS_ID });
                        }
                        return acc;
                    }, []);
                Combox(uniqueProcess, process, false);
            });
            function loadData(selectElement, url, boolean) {
                $.ajax({
                    type: "POST",
                    url: url,
                    dataType: "json",
                    async: false,
                    success: function (data) {
                        var uniqueProjCodes = Object.values(data.ReturnData.Table.reduce((acc, item) => {
                            acc[item.PROJ_CODE] = { value: item.PROJ_CODE, text: item.PROJECT };
                            return acc;
                        }, {}));
                        select_dt = data.ReturnData.Table;
                        Combox(uniqueProjCodes, selectElement, boolean);
                    }
                });
            }
            function Combox(selectdata, selectElement, boolean) {
                selectElement.empty();
                if (boolean) {
                    selectElement.append("<option value=''>@Html.Raw(Label.PleaseSelect)...</option>");
                } else {
                    selectElement.append("<option value='ALL'>@Html.Raw(Label.ALL)</option>");
                }
                $.each(selectdata, function (key, value) {
                    selectElement.append($('<option>', {
                        value: value.value,
                        text: value.text
                    }));
                });
            }
        }

        $(function () {
            var startDate = new Date();
            startDate.setDate(startDate.getDate() - 7);
            startDate.setHours(7, 0, 0, 0);
            var endDate = new Date();
            endDate.setDate(endDate.getDate() + 1);
            endDate.setHours(7, 0, 0, 0);
            //$('#startdate').val(startDate.toISOString().split('T')[0]);
            //$('#enddate').val(endDate.toISOString().split('T')[0]);
            var startdatetime = startDate.toLocaleDateString('sv-SE') + 'T' + startDate.toTimeString().slice(0, 5);
            $('#startdate').val(startdatetime);
            var enddatetime = endDate.toLocaleDateString('sv-SE') + 'T' + endDate.toTimeString().slice(0, 5);
            $('#enddate').val(enddatetime);
            ComboxAction();
            setTimeout(function () {
                $('#cmb_prod_type').val('Normal').change();
                $('#cmb_proj_code').val('NCCSAD').trigger('change');
                Getdata();
            }, 850);
        })

        var Getdata = function () {
            getdate();
            TabInterval();
        }

        /*报表导出*/
        var ExportType;
        var DeviceAssemblyExport = function (type) {
            ExportType = type;
            var formData = new FormData();
            formData.append('excelname', ExportType);
            formData.append('prodtype', $('#cmb_prod_type').val());
            formData.append('proj_code', $('#cmb_proj_code').val());
            formData.append('process_id', $('#cmb_process_code').val() == null ? "ALL" : $('#cmb_process_code').val());
            formData.append('start', $("#startdate").val());
            formData.append('end', $("#enddate").val());
            var url = api + "/ReportAction/GetDeviceAssemblyYieldToExcel";
            PostExportToExcel(url, formData);
            alert("数据量过大。。。\n\n正在加速下载，请等待2分钟^_^");
        }
        //POST 参数不固定 导出
        var PostExportToExcel = function (url, formData) {
            //GET: var url = "http://localhost:44304/Dashboard/ExportToExcel?" + $.param(pam);
            var xhr = new XMLHttpRequest();
            xhr.open('POST', url, true);
            xhr.responseType = 'blob';
            xhr.onload = function () {
                if (xhr.status === 200) {
                    var url = window.URL.createObjectURL(xhr.response);
                    var a = document.createElement('a');
                    a.href = url;
                    a.download = ExportType.toLocaleUpperCase() + '.xlsx';
                    a.click();
                    window.URL.revokeObjectURL(url);
                }
            };
            xhr.send(formData);
        }

        /*Tab手动切换*/
        function OpenTab(evt, panle, id, echar_name, itemindex = -1) {
            var i, tablinks;
            tablinks = document.getElementsByClassName(panle)[0].getElementsByClassName("tablinks");
            for (i = 0; i < tablinks.length; i++) {
                tablinks[i].className = tablinks[i].className.replace("active", "");
            }
            evt.currentTarget.className += " active";
            if(panle =='tab-chart'){
                var chart = echarts.init(document.getElementById("process_yield"));
                chart.dispose();
            }
            echar_name();
        }

        var tablinksonclick = function (switch_on) {
            $('#process_input').val('ALL');
            $('#cmb_data_type').val('DAY');
            var i, tablinks;
            tablinks = document.getElementsByClassName('tab-chart')[0].getElementsByClassName("tablinks");
            for (i = 0; i < tablinks.length; i++) {
                tablinks[i].className = tablinks[i].className.replace("active", "");
            }
            switch (switch_on) {
                case "ProcessYield":
                    tablinks[0].className += " active";
                    $(".search").show();
                    $("#cmb_type").show();
                    $('#cmb_yield_type').show();
                    $('#cmb_yield_type').val('final_yield');
                    $('#cmb_data_type').show();
                    $('#cmb_tester_type').hide();
                    break;
                case "FailureModeRate":
                    tablinks[1].className += " active";
                    $(".search").css("display", "block");
                    $("#cmb_type").css("display", "block");
                    $('#cmb_data_type').show();
                    $('#cmb_yield_type').hide();
                    $('#cmb_tester_type').hide();
                    break;
                case "TesterYieldFailureMode":
                    tablinks[2].className += " active";
                    $(".search").show();
                    $("#cmb_type").show();
                    $('#cmb_yield_type').hide();
                    $('#cmb_data_type').hide();
                    $('#cmb_tester_type').show();
                    break;
            }
        }

        //process 搜索下拉绑定
        var process_search_binding = function () {
            var processSearch = $('#process_search');
            processSearch.empty();
            var processSet = new Set();
            $.each(Tab.Table3, function (index, item) {
                var process = item.PROCESS_ID.trim();
                processSet.add(process);
            });
            processSearch.append($('<option>').val('ALL'));
            processSet.forEach(function (process) {
                processSearch.append($('<option>').val(process));
            });
            $('#process_input').val('ALL');
        }

        var tester_binding = function(select) {
            var tester_type = $('#cmb_tester_type');
            var filtered = (select && select !== 'ALL') ? Tab.Table7.filter(x => x.PROCESS_ID === select) : Tab.Table7;
            var testerList = filtered.map(x => x.TESTER);
            var uniqueTesters = [...new Set(testerList)].sort();
            tester_type.empty();
            tester_type.append('<option value="ALL">ALL</option>');
            uniqueTesters.forEach(t => {
                tester_type.append(`<option value="${t}">${t}</option>`);
            });
            tester_type.val('ALL');
        };

        //下拉月周日页签联动
        $('#process_input,#cmb_data_type,#cmb_yield_type,#cmb_tester_type').on('change', function () {
            var i, tablinks, fun, action;
            tablinks = document.getElementsByClassName("tab-chart")[0].getElementsByClassName("tablinks");
            for (i = 0; i < tablinks.length; i++) {
                if (tablinks[i].className.includes("active")) {
                    switch (i) {
                        case 0:
                            action = "ProcessYield";
                            fun = processyieldchart;
                            break;
                        case 1:
                            action = "FailureModeRate";
                            fun = failuremodeareachart;
                            break;
                        case 2:
                            action = "TesterYieldFailureMode";
                            fun = testeryieldfailuremodechart;
                            if (this.id === 'process_input') {
                                const processVal = $('#process_input').val() || 'ALL'; 
                                tester_binding(processVal);
                            }
                            break;
                    }
                }
            }
            updateTabChart(fun, action);
        });

        function getExcelColor(percentage) {
            let red, green, blue;
            if (percentage === 0) {
                red = 53;
                green = 250;
            } else if (percentage <= 5) {
                red = 255;
                green = Math.round((5 - percentage) / 5* 255);
            } else if (percentage <= 20) {
                red = 255;
                green = Math.round(255 - ((percentage - 5) / 15) * 255);
            } else if (percentage <= 50) {
                red = Math.round(255 - ((percentage - 20) / 30) * 50);
                green = 0;
            } else if (percentage <= 100) {
                red = Math.round(205 + ((percentage - 50) / 50) * 50);
                green = 0;
            }
            return `rgb(${red}, ${green}, 150)`;
        }

        function loadingshow() {
            $('#left-table,#process_container,#failuremode').css('background-image', 'url("../images/loading.gif")');
            $('#left-table,#process_container,#failuremode').css('background-size', '0.8rem 0.8rem');
            $('#left-table,#process_container,#failuremode').css('background-repeat', 'no-repeat');
            $('#left-table,#process_container,#failuremode').css('background-position', 'center');
        }
        function loadingnone() {
            $('#left-table,#process_container,#failuremode').css('background-image', 'none');
        }

        //获取数据
        var Tab;
        var getdate = function () {
            $('#btn_query').prop('disabled', true);
            var header_key = {
                start: $('#startdate').val(),
                end: $('#enddate').val()
            };
            var pam = {};
            pam.proj_code = $('#cmb_proj_code').val();
            pam.process_id = $('#cmb_process').val();
            pam.type = $('#cmb_prod_type').val()
            pam.header_key = JSON.stringify(header_key);
            if (pam.proj_code !== "-1") {
                loadingshow();
                $("#left-table-body").empty();
                $("#myTable").empty();
                $.ajax({
                    type: "POST",
                    url: api + "/ReportAction/GetDeviceAssemblyYield",
                    data: pam,
                    dataType: "json",
                    async: true,
                    success: function (dt) {
                        loadingnone();
                        $('#btn_query').prop('disabled', false);
                        $('#cmb_yield_type').val('final_yield');
                        $('#cmb_yield_type').show();
                        Tab = dt.ReturnData;
                        process_search_binding();
                        tester_binding('ALL');
                        ProcessYieldBoard();
                        ProcessYieldChartFun();
                        platoChart();
                    }
                });
            }
        }
        
        //工序良率
        var ProcessYieldBoard = function () {
            $('#btn_query').prop('disabled', false);
            var data = Tab.Table;
            $("#myTable").empty();
            $("#left-table-body").empty();
            var left_table_html = `
            <table id="myTable" class="DataSheet" border="1" style="width: 100%; height: 100%;">
                <thead><tr></tr></thead>
                <tbody id="yield_tbody"></tbody>
                <tfoot><tr></tr></tfoot>
            </table`;
            $("#left-table-body").append(left_table_html);
            var table = $('#myTable');
            var tbody = table.find('tbody');
            var headerRow = table.find('thead tr');
            var headers = Object.keys(data[0]).filter(key => !['ROW_NUM', 'ROWSPAN'].includes(key));
            headers.forEach(function (header) {
                headerRow.append('<th>' + header + '</th>');
            });
            var primeyield, finalyield;
            for (var i = 0; i < data.length; i++) {
                var table_tr_dt = "";
                if (data[i].ROWSPAN && parseInt(data[i].ROWSPAN) > 0) {
                    table_tr_dt += '<td class="tabletd" rowspan=' + parseInt(data[i].ROWSPAN) + '>' + data[i].PROCESS_ID + '</td>'
                        + '<td class="tabletd" rowspan=' + parseInt(data[i].ROWSPAN) + '>' + data[i].TTL_INPUT + '</td>'
                        + '<td class="tabletd" rowspan=' + parseInt(data[i].ROWSPAN) + '>' + data[i].THREE_TIMES_LAST_FAIL + '</td>'
                        + '<td class="tabletd" rowspan=' + parseInt(data[i].ROWSPAN) + '>' + data[i].PRIME_YIELD + '</td>'
                        + '<td class="tabletd" rowspan=' + parseInt(data[i].ROWSPAN) + '>' + data[i].FINAL_FAIL + '</td>'
                        + '<td class="tabletd" rowspan=' + parseInt(data[i].ROWSPAN) + '>' + data[i].FINAL_YIELD + '</td>'
                        + '<td>' + data[i].FAILURE_MODE + '</td>'
                        + '<td class="tabletd">' + data[i].PRIME_REJECT + '</td>'
                        + '<td class="tabletd">' + data[i].PRIME_REJECT_RATE + '</td>'
                        + '<td class="tabletd">' + data[i].RETEST_PASS + '</td>'
                        + '<td class="tabletd">' + data[i].FINAL_REJECT + '</td>'
                        + '<td class="tabletd">' + data[i].FINAL_REJECT_RATE + '</td>';

                    var primeyieldFloat = parseFloat(data[i].PRIME_YIELD.substring(0, data[i].PRIME_YIELD.indexOf("%"))) / 100;
                    var finalyieldFloat = parseFloat(data[i].FINAL_YIELD.substring(0, data[i].FINAL_YIELD.indexOf("%"))) / 100;
                    if (!(primeyield)) {
                        primeyield = (primeyieldFloat > 0 ? primeyieldFloat : 1);
                    }
                    else {
                        primeyield = primeyield * (primeyieldFloat > 0 ? primeyieldFloat : 1);
                    }
                    if (!(finalyield)) {
                        finalyield = (finalyieldFloat > 0 ? finalyieldFloat : 1);
                    }
                    else {
                        finalyield = finalyield * (finalyieldFloat > 0 ? finalyieldFloat : 1);
                    }
                }
                else {
                    table_tr_dt += '<td>' + data[i].FAILURE_MODE + '</td>'
                        + '<td class="tabletd">' + data[i].PRIME_REJECT + '</td>'
                        + '<td class="tabletd">' + data[i].PRIME_REJECT_RATE + '</td>'
                        + '<td class="tabletd">' + data[i].RETEST_PASS + '</td>'
                        + '<td class="tabletd">' + data[i].FINAL_REJECT + '</td>'
                        + '<td class="tabletd">' + data[i].FINAL_REJECT_RATE + '</td>';
                }
                var newRow = $(`<tr class="ZebraTo">${table_tr_dt}</tr>`);
                tbody.append(newRow);
            }
            var tfootRow = table.find('tfoot tr');
            tfootRow.append(`<th id="sum" colspan="3">汇总</th><th id="primeyield">${parseFloat((primeyield * 100).toFixed(2)) + "%"}</th><th></th><th id="finalyield">${parseFloat((finalyield * 100).toFixed(2)) + "%"}</th><th colspan="6"></th>`);
        }

        //设备Fail
        function TesterFailBoard(){
            $('#btn_query').prop('disabled', false);
            var data = Tab.Table1;
            $("#TesterTable").empty();
            $("#left-table-body").empty();
            var left_table_html = `
            <table id="testertable" class="DataSheet" border="1" style="width: 100%; height: 100%;">
                <thead><tr></tr></thead>
                <tbody id="tester_tbody"></tbody>
            </table`;
            $("#left-table-body").append(left_table_html);
            var tester_table = $('#testertable');
            var tester_tbody = tester_table.find('tbody');
            var tester_headerRow = tester_table.find('thead tr');
            $("#testertable>thead>tr, #tester_tbody").empty();
            // 动态生成表头
            var tester_headers = Object.keys(data[0]);
            tester_headers.forEach(function (header) {
                tester_headerRow.append('<th>' + header + '</th>');
            });
            // 生成表格内容
            data.forEach(function (row, index) {
                index++;
                var tdvaule;
                var newRow = $(`<tr class="${(index % 2) > 0 ? "ZebraNo" : "ZebraTo"}"></tr>`);
                tester_headers.forEach(function (header, columnindex) {
                    tdvaule = row[header];
                    if (!["PROCESS_ID", "TESTER", "INPUT", "FALI"].includes(header)) {
                        tdvaule = parseFloat(row[header]).toFixed(2) + '%';
                    }
                    if (!["PROCESS_ID", "TESTER", "INPUT", "FALI"].includes(header)) {
                        newRow.append(`<td class="percentage">${tdvaule}</td>`);
                    }
                    else {
                        newRow.append(`<td class="truncate">${tdvaule}</td>`);
                    }
                });
                tester_tbody.append(newRow);
            });
            $('.percentage').each(function() {
                const percentage = Math.ceil(parseFloat($(this).text().replace('%', '')));
                $(this).css('background-color', getExcelColor(percentage));
            });
        }

        //updateChart
        var updateTabChart = function (fun, actionname) {
            var process = $('#process_input').val();
            var cl_type = $('#cmb_data_type').val();
            if (!fun) return;
            var updatechartdata;
            const actionMap = {
                ProcessYield: {
                    day: Tab.Table2,
                    week: Tab.Table3,
                    updateFunc: updateProcessYieldChartOptions
                },
                FailureModeRate: {
                    day: Tab.Table4,
                    week: Tab.Table5,
                    updateFunc: updateFailureModeAreaChartOptions
                },
                TesterYieldFailureMode: {
                    day: Tab.Table7,
                    week: Tab.Table8,
                    updateFunc: updateTesterYieldFailureModeChartOptions
                },
            };
            const dataZoomConfig = [
                {
                    type: 'inside',
                    start: 0,
                    end: 100,
                    xAxisIndex: [0, 1]
                },
                {
                    type: 'slider',
                    start: 0,
                    end: 100,
                    xAxisIndex: [0, 1],
                    handleSize: 0,
                    height: "0.3rem",
                    show: false,
                    zoomOnMouseWheel: true
                }
            ];
            for (let key in actionMap) {
                if (actionname == key) {
                    const actionConfig = actionMap[key];
                    updatechartdata = actionConfig[cl_type.toLowerCase()];
                    if (process !== "ALL") {
                        updatechartdata = updatechartdata.filter(item => item.PROCESS_ID == process);
                    }
                    actionConfig.updateFunc(updatechartdata, dataZoomConfig);
                    break;
                }
            }
        };

        //ProcessYield: (Process,week/Day)
        var processyieldchart;
        function ProcessYieldChartFun() {
            tablinksonclick("ProcessYield");
            var chartData = Tab.Table2;
            var chartDom = document.getElementById("process_yield");
            if (chartDom) {
                echarts.dispose(chartDom);
            }
            processyieldchart = echarts.init(chartDom);
            updateProcessYieldChartOptions(chartData, null);
        }
        var updateProcessYieldChartOptions = function (chartData, dataZoomConfig) {
            var allDates = Array.from(new Set(chartData.map(item => item.DATE))).sort((a, b) => a - b);
            var groupedData = {};
            chartData.forEach(function (item) {
                if (!groupedData[item.PROCESS_ID]) {
                    groupedData[item.PROCESS_ID] = {
                        date: allDates,
                        final_yield: Array(allDates.length).fill(null),
                        prime_yield	: Array(allDates.length).fill(null)
                    };
                }
                var index = allDates.indexOf(item.DATE);
                if (index !== -1) {
                    groupedData[item.PROCESS_ID].final_yield[index] = parseFloat(item.FINAL_YIELD.replace('%', ''));
                    groupedData[item.PROCESS_ID].prime_yield[index] = parseFloat(item.PRIME_YIELD.replace('%', ''));
                }
            });
            var yieldType = $('#cmb_yield_type').val(); 
            var seriesData = Object.keys(groupedData).map(function (processId) {
                return {
                    name: processId,
                    type: 'line',
                    data: groupedData[processId][yieldType],
                    emphasis: {
                        focus: 'series',
                        lineStyle: { opacity: 1 },
                        itemStyle: { opacity: 1 }
                    },
                    label: {
                        show: false,
                        formatter: params => `${params.value || 0}%`
                    },
                    lineStyle: {
                        width: 3
                    },
                    itemStyle: {
                        borderWidth: 2
                    },
                    symbolSize: 8
                };
            });
            var xAxisdata;
            if ($('#cmb_data_type').val() === 'WEEK') {
                xAxisdata = chartData.map(item => item.DATE).filter((value, index, self) => self.indexOf(value) === index);
            }
            else {
                xAxisdata = Array.from(new Set(chartData.map(item => item.DATE))).sort((a, b) => new Date(`2024-${a.replace("-", "/")}`) - new Date(`2024-${b.replace("-", "/")}`));
            }
            var option = {
                textStyle: {
                    fontSize: '0.14rem'
                },
                tooltip: {
                    show: true,
                    trigger: 'axis',
                    color: 'red',
                    textStyle: {
                        fontSize: '0.14rem'
                    },
                    axisPointer: {
                        type: 'cross',
                    },
                    formatter: function (params) {
                        let tooltipText = `<div class="tooltip">${params[0].axisValue}</div><table>`;
                        params.forEach(function (item) {
                            let dataItem = chartData.find(data => data.DATE == item.axisValue && data.PROCESS_ID == item.seriesName);
                            if (dataItem) {
                                tooltipText += `
                                <tr>
                                    <td class="tooltip">${item.marker}${item.seriesName}</td>
                                    <td class="tooltip">Input: ${dataItem.INPUT}</td>
                                    <td class="tooltip">PrimeReject: ${dataItem.PRIME_REJECT}</td>
                                    <td class="tooltip">FinalReject: ${dataItem.FINAL_REJECT}</td>
                                    <td class="tooltip">PrimeYield: ${dataItem.PRIME_YIELD}</td>
                                    <td class="tooltip">FinalYield: ${dataItem.FINAL_YIELD}</td>
                                </tr>`;
                            }
                        });
                        tooltipText += '</table>';
                        return tooltipText;
                    }
                },
                legend: {
                    show: true,
                    type: 'scroll',
                    width: '100%',
                    data: Object.keys(groupedData),
                    orient: 'horizontal',
                    itemWidth: 12,
                    itemHeight: 12,
                    scrollDataIndex: 0,
                    pageIconSize: [16, 16],
                    pageIconColor: '#0aa9cd',
                    pageTextStyle: {
                        fontSize: '0.14rem'
                    },
                    textStyle: {
                        fontSize: '0.14rem'
                    },
                    pageButtonItemHoverColor: '#9dddeb'
                },
                grid: {
                    top: '20%',
                    left: '7%',
                    right: '2%',
                    bottom: '10%',
                    width: '90%',
                },
                xAxis: {
                    type: 'category',
                    boundaryGap: false,
                    data: allDates,
                    axisLine: {
                        show: false
                    },
                    axisTick: {
                        show: true
                    },
                    axisLabel: {
                        textStyle: {
                            fontSize: '0.14rem',
                            fontWeight: 'bold'
                        },
                        show: true
                    }
                },
                yAxis: {
                    type: 'value',
                    name: `${$('#cmb_yield_type').val().toUpperCase()}(%)`,
                    scale: true,
                    axisTick: {
                        show: true
                    },
                    axisLabel: {
                        formatter: function (value) {
                            return value + '%';
                        },
                        textStyle: {
                            fontSize: '0.14rem',
                            fontWeight: 'bold'
                        },
                        show: true
                    }
                },
                series: seriesData,
                dataZoom: dataZoomConfig
            };
            processyieldchart.setOption(option, true);
        };

        //FailureModeRate: (FailureMode,week/Day)
        var failuremodeareachart;
        function FailureModeAreaChartFun() {
            tablinksonclick("FailureModeRate");
            var chartData = Tab.Table4;
            var chartDom = document.getElementById("process_yield");
            if (chartDom) {
                echarts.dispose(chartDom);
            }
            failuremodeareachart = echarts.init(chartDom);
            updateFailureModeAreaChartOptions(chartData, null);
        }
        var updateFailureModeAreaChartOptions = function (chartData, dataZoomConfig) {
            var xAxisdata;
            if ($('#cmb_data_type').val() === 'WEEK') {
                xAxisdata = chartData.map(item => item.DATE)
                    .filter((value, index, self) => self.indexOf(value) === index)
                    .sort((a, b) => a - b);
            }
            else {
                xAxisdata = chartData
                    .map(item => item.DATE)
                    .filter((value, index, self) => self.indexOf(value) === index)
                    .sort((a, b) => new Date(`2024-${a.replace("-", "/")}`) - new Date(`2024-${b.replace("-", "/")}`));
            }
            var groupedData = {};
            chartData.forEach(function (item) {
                if (!groupedData[item.FAILURE_MODE]) {
                    groupedData[item.FAILURE_MODE] = {
                        DATE: [...xAxisdata],
                        REJECT_RATE: new Array(xAxisdata.length).fill(null)
                    };
                }
                var index = xAxisdata.indexOf(item.DATE);
                groupedData[item.FAILURE_MODE].REJECT_RATE[index] = parseInt(item.PRIME_REJECT_RATE.replace('%', ''));
            });
            var colorList = [
                ['#80FFA5', '#00FF88'],
                ['#00DDFF', '#0096FF'],
                ['#37A2FF', '#188DF0'],
                ['#FF0087', '#FF5D77'],
                ['#FFBF00', '#FFD700'],
                ['#FF7F50', '#FF4500'],
                ['#FF6347', '#FF4500'],
                ['#FFA07A', '#FF6347'],
                ['#FFD700', '#FFBF00'],
                ['#FFC1C1', '#FF6A6A'],
                ['#FFA500', '#FF8C00'],
                ['#FFDAB9', '#FFC1C1']
            ];
            var seriesData = Object.keys(groupedData).map(function (defect, index) {
                var colorGradient = colorList[index % colorList.length];
                return {
                    name: defect,
                    type: 'line',
                    stack: 'Total',
                    smooth: false,
                    showSymbol: false,
                    lineStyle: { width: 0 },
                    emphasis: {
                        focus: 'series',
                        lineStyle: { opacity: 1 },
                        itemStyle: { opacity: 1 }
                    },
                    areaStyle: {
                        normal: {
                            opacity: 0.8,
                            color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
                                { offset: 0, color: colorGradient[0] },
                                { offset: 1, color: colorGradient[1] }
                            ])
                        }
                    },
                    data: groupedData[defect].REJECT_RATE.map(value => value === null ? 0 : value)
                };
            });
            var option = {
                color: Object.keys(groupedData).map(function (defect, index) {
                    return colorList[index % colorList.length][0];
                }),
                textStyle: {
                    fontSize: '0.14rem'
                },
                tooltip: {
                    show: true,
                    trigger: 'axis',
                    textStyle: {
                        fontSize: '0.14rem'
                    },
                    axisPointer: {
                        type: 'cross',
                    },
                    formatter: function (params) {
                        let sortedParams = params.slice().sort((a, b) => b.data - a.data);
                        let tooltipText = `<div class="tooltip">${params[0].axisValue}</div><table>`;
                        if ($('#process_input').val() == "ALL") {
                            var td;
                            var index = 0;
                            sortedParams.forEach(item => {
                                let dataItem = chartData.find(data => data.DATE == item.axisValue && data.FAILURE_MODE == item.seriesName);
                                if (dataItem) {
                                    td += `
                                    <td class="tooltip">${item.marker}${item.seriesName}</td>
                                    <td class="tooltip">FinalRejectRate: ${dataItem.FINAL_REJECT_RATE}</td>`;
                                    index++;
                                }
                                if (index % 2 == 0 || index == sortedParams.length) {
                                    td = String(td).replace('undefined', '');
                                    tooltipText += `<tr>${td}</tr>`;
                                    td = "";
                                }
                            });
                        }
                        else {
                            sortedParams.forEach(item => {
                                let dataItem = chartData.find(data => data.DATE == item.axisValue && data.FAILURE_MODE == item.seriesName);
                                if (dataItem) {
                                    tooltipText += `
                                    <tr>
                                        <td class="tooltip">${item.marker}${item.seriesName}</td>
                                        <td class="tooltip">Process: ${dataItem.PROCESS_ID}</td>
                                        <td class="tooltip">Input: ${dataItem.INPUT}</td>
                                        <td class="tooltip">PrimeReject: ${dataItem.PRIME_REJECT}</td>
                                        <td class="tooltip">FinalReject: ${dataItem.FINAL_REJECT}</td>
                                        <td class="tooltip">PrimeYield: ${dataItem.PRIME_YIELD}</td>
                                        <td class="tooltip">FinalYield: ${dataItem.FINAL_YIELD}</td>
                                        <td class="tooltip">FailureReject: ${dataItem.FAILURE_MODE_PRIME_REJECT}</td>
                                        <td class="tooltip">FailureFinal: ${dataItem.FAILURE_MODE_FINAL_REJECT}</td>
                                        <td class="tooltip">FailureRejectRate: ${dataItem.PRIME_REJECT_RATE}</td>
                                        <td class="tooltip">FailureFinalRate: ${dataItem.FINAL_REJECT_RATE}</td>
                                    </tr>`;
                                }
                            });
                        }
                        tooltipText += '</table>';
                        return tooltipText;
                    }
                },
                legend: {
                    show: true,
                    type: 'scroll',
                    width: '100%',
                    data: Object.keys(groupedData),
                    orient: 'horizontal',
                    itemWidth: 12,
                    itemHeight: 12,
                    scrollDataIndex: 0,
                    pageIconSize: [16, 16],
                    pageIconColor: '#0aa9cd',
                    pageTextStyle: {
                        fontSize: '0.14rem'
                    },
                    textStyle: {
                        fontSize: '0.14rem'
                    },
                    pageButtonItemHoverColor: '#9dddeb'
                },
                grid: {
                    top: '20%',
                    left: '7%',
                    right: '2%',
                    bottom: '10%',
                    width: '90%',
                },
                xAxis: {
                    type: 'category',
                    boundaryGap: false,
                    data: xAxisdata,
                    axisLine: {
                        show: false
                    },
                    axisTick: {
                        show: true
                    },
                    axisLabel: {
                        textStyle: {
                            fontSize: '0.14rem',
                            fontWeight: 'bold'
                        },
                        show: true
                    }
                },
                yAxis: {
                    type: 'value',
                    name: 'FinalReject',
                    min: 0,
                    axisTick: {
                        show: true
                    },
                    axisLabel: {
                        formatter: function (value) {
                            return value + '%';
                        },
                        textStyle: {
                            fontSize: '0.14rem',
                            fontWeight: 'bold'
                        },
                        show: true
                    }
                },
                series: seriesData,
                dataZoom: dataZoomConfig
            };
            failuremodeareachart.setOption(option, true);
            window.addEventListener('resize', function () {
                failuremodeareachart.resize();
            });
        };

        //TesterYieldFailureModeChartFun
        var testeryieldfailuremodechart;
        function TesterYieldFailureModeChartFun() {
            tablinksonclick("TesterYieldFailureMode");
            var chartData = Tab.Table7;
            const uniqueMap = new Map();
            chartData.forEach(item => {
              const key = `${item.PROJ_CODE}_${item.PROCESS_ID}_${item.TESTER}_${item.DATE}`;
              if (!uniqueMap.has(key)) {
                //只保留需要的字段
                uniqueMap.set(key, {
                    PROJ_CODE: item.PROJ_CODE,
                    PROCESS_ID: item.PROCESS_ID,
                    TESTER: item.TESTER,
                    INPUT: item.INPUT,
                    PRIME_FAIL: item.PRIME_FAIL,
                    PRIME_YIELD: item.PRIME_YIELD,
                    FINAL_FAIL: item.FINAL_FAIL,
                    FINAL_YIELD: item.FINAL_YIELD,
                    DATE: item.DATE
                });
              }
            });
            //转为数组
            const result = Array.from(uniqueMap.values());
            var chartDom = document.getElementById("process_yield");
            if (chartDom) {
                echarts.dispose(chartDom);
            }
            testeryieldfailuremodechart = echarts.init(chartDom);
            updateTesterYieldFailureModeChartOptions(result, null);
        }
        var updateTesterYieldFailureModeChartOptions = function (chartData, dataZoomConfig) {
            const testerFilter = $("#cmb_tester_type").val();
            const processFilter = $('#process_input').val();
            let filtered = chartData.filter(item => {
                const matchTester = (testerFilter === "ALL" || testerFilter === "" || item.TESTER === testerFilter);
                const matchProcess = (processFilter === "ALL" || processFilter === "" || item.PROCESS_ID === processFilter);
                return matchTester && matchProcess;
            });

            var allDates = Array.from(new Set(filtered.map(item => item.DATE))).sort((a, b) => a - b);
            var groupedData = {};
            filtered.forEach(function (item) {
                if (!groupedData[item.TESTER]) {
                    groupedData[item.TESTER] = {
                        date: allDates,
                        final_yield: Array(allDates.length).fill(null),
                        prime_yield	: Array(allDates.length).fill(null)
                    };
                }
                var index = allDates.indexOf(item.DATE);
                if (index !== -1) {
                    groupedData[item.TESTER].prime_yield[index] = parseFloat(item.PRIME_YIELD.replace('%', ''));
                    groupedData[item.TESTER].final_yield[index] = parseFloat(item.FINAL_YIELD.replace('%', ''));
                }
            });
            var yieldType = $('#cmb_yield_type').val();
            var seriesData = Object.keys(groupedData).map(function (processId) {
                return {
                    name: processId,
                    type: 'line',
                    data: groupedData[processId]['prime_yield'],
                    emphasis: {
                        focus: 'series',
                        lineStyle: { opacity: 1 },
                        itemStyle: { opacity: 1 }
                    },
                    label: {
                        show: false,
                        formatter: params => `${params.value || 0}%`
                    },
                    lineStyle: {
                        width: 3
                    },
                    itemStyle: {
                        borderWidth: 2
                    },
                    symbolSize: 8
                };

            });
            var xAxisdata = filtered.map(item => item.DATE).filter((value, index, self) => self.indexOf(value) === index);
            var option = {
                tooltip: {
                    trigger: 'item',
                    axisPointer: { type: 'line' },
                    show: true,
                    formatter: function (params) {
                        const date = params.name;
                        const filtered = Tab.Table7.filter(d => d.DATE === date && d.TESTER === params.seriesName && d.PRIME_FAIL > 0);
                        if (filtered.length === 0) return '';
                        const summary = filtered[0];
                        const failureModes = filtered;
                        let html = `<div style="padding:4px 8px;"><strong>Tester By Failure Mode(${date})</strong></div>`;
                        html += `<table id='testerfailure' style="border-collapse: collapse; width: 100%; font-size:10px;">`;
                        //PROCESS 汇总行标题
                        html += `
                        <tr>
                            <th style="text-align:left;">Tester</th>
                            <th>Input</th>
                            <th>Output</th>
                            <th>Fail</th>
                            <th>PrimeYield</th>
                            <th>RetestPass</th>
                            <th>FinalYield</th>
                        </tr>`;
                        //汇总数据行
                        html += `
                        <tr>
                            <td>${params.marker} ${summary.TESTER}</td>
                            <td>${summary.INPUT}</td>
                            <td>${summary.INPUT - summary.PRIME_FAIL}</td>
                            <td>${summary.PRIME_FAIL}</td>
                            <td>${summary.PRIME_YIELD}</td>
                            <td>${summary.PRIME_FAIL - summary.FINAL_FAIL}</td>
                            <td>${summary.FINAL_YIELD}</td>
                        </tr>`;
                        //子表标题行（FAILURE_MODE 合并三格）
                        html += `
                        <tr>
                            <th colspan="3">FailureMode</th>
                            <th>PrimeReject</th>
                            <th>PrimeRejectRate</th>
                            <th>RetestPass</th>
                            <th>FinalRejectRate</th>
                        </tr>`;
                        //子项数据行
                        failureModes.forEach(d => {
                            html += `
                            <tr>
                                <td colspan="3">${d.FAILURE_MODE}</td>
                                <td>${d.PRIME_REJECT}</td>
                                <td>${d.PRIME_RATE}</td>
                                <td>${d.RETEST_PASS}</td>
                                <td>${d.FINAL_RATE}</td>
                            </tr>`;
                        });
                        html += `</table>`;
                        return html;
                    }
                },
                legend: {
                    show: true,
                    type: 'scroll',
                    width: '98%',
                    data: Object.keys(groupedData),
                    orient: 'horizontal',
                    itemWidth: 12,
                    itemHeight: 12,
                    scrollDataIndex: 0,
                    pageIconSize: [16, 16],
                    pageIconColor: '#0aa9cd',
                    pageTextStyle: {
                        fontSize: '0.16rem'
                    },
                    textStyle: {
                        fontSize: '0.16rem',
                        fontWeight: 'bold'
                    },
                    pageButtonItemHoverColor: '#9dddeb'
                },
                grid: {
                    top: '20%',
                    left: '7%',
                    right: '2%',
                    bottom: '10%',
                    width: '90%',
                },
                xAxis: {
                    type: 'category',
                    data: allDates,
                    boundaryGap: false,
                    axisLine: {
                        show: false
                    },
                    axisTick: {
                        show: true
                    },
                    axisLabel: {
                        textStyle: {
                            fontSize: '0.14rem',
                            fontWeight: 'bold'
                        },
                        show: true
                    }
                },
                yAxis: {
                    type: 'value',
                    name: 'PrimeYield(%)',
                    scale: true,
                    axisTick: {
                        show: true
                    },
                    axisLabel: {
                        formatter: function (value) {
                            return value + '%';
                        },
                        textStyle: {
                            fontSize: '0.14rem',
                            fontWeight: 'bold'
                        },
                        show: true
                    }
                },
                series: seriesData,
                dataZoom: dataZoomConfig
            };

            testeryieldfailuremodechart.setOption(option, true);
            window.addEventListener('resize', function () {
                testeryieldfailuremodechart.resize();
            });
        };

        //FailureMode Pareto
        var plato_optionloop;
        function platoChart() {
            var chart = document.getElementById("failuremode_pareto");
            var myChart = echarts.init(chart);
            var item = [];
            var itemvaule = [];
            var linevaule = [];
            var lastvaule;
            if (Tab) {
                for (var i = 0; i < Tab.Table6.length; i++) {
                    item.push(Tab.Table6[i].FAILURE_MODE);
                    itemvaule.push(parseInt(Tab.Table6[i].FAILURE_MODE_FINAL_REJECT));
                    if (i == 0) {
                        lastvaule = parseInt(Tab.Table6[i].PARETO.replace('%', ''));
                        linevaule.push(Tab.Table6[i].PARETO.replace('%', ''));
                    } else {
                        lastvaule = lastvaule + parseInt(Tab.Table6[i].PARETO.replace('%', ''));
                        linevaule.push(lastvaule.toFixed(2));
                    }
                }
            };
            var option = {
                title: {
                    text: 'FailureMode Pareto',
                    textStyle: {
                        fontSize: '0.16rem',
                        color: '#0aa9cd'
                    }
                },
                tooltip: {
                    trigger: 'axis',
                    axisPointer: {
                        type: 'cross',
                        crossStyle: {
                            color: 'white'
                        }
                    }
                },
                grid: {
                    top: '15%',
                    left: '6%',
                    right: '6%',
                    bottom: '15%',
                    width: '86%',
                },
                xAxis: {
                    type: 'category',
                    data: item,
                    axisLabel: {
                        interval: item.length >= 50 ? Math.ceil(item.length / 50) : 0,
                        rotate: 45,
                        textStyle: {
                            fontSize: '0.14rem',
                            fontWeight: 'bold'
                        }
                    },
                    textStyle: {
                        fontSize: '0.14rem'
                    }
                },
                yAxis: [
                    {
                        type: 'value',
                        position: 'left',
                        axisLine: {
                            show: false
                        },
                        axisTick: {
                            show: true
                        },
                        axisLabel: {
                            textStyle: {
                                fontSize: '0.14rem',
                                fontWeight: 'bold'
                                
                            },
                            show: true
                        },
                        splitLine: {
                            show: false
                        }
                    },
                    {
                        type: 'value',
                        name: 'Pareto(%)',
                        position: 'right',
                        axisLine: {
                            show: false
                        },
                        axisTick: {
                            show: true
                        },
                        splitLine: {
                            show: false
                        },
                        axisLabel: {
                            show: true,
                            formatter: '{value}%',
                            textStyle: {
                                fontSize: '0.14rem',
                                fontWeight: 'bold'
                            }
                        }
                    }
                ],
                series: [
                    {
                        name: 'FinalReject',
                        type: 'bar',
                        itemStyle: {
                            normal: {
                                barBorderRadius: [10, 10, 0, 0],
                                color: new echarts.graphic.LinearGradient(0, 1, 0, 0, [{
                                    offset: 0,
                                    color: "#009AFD"
                                }, {
                                    offset: 0.8,
                                    color: "#33DAFF"
                                }], false),
                                shadowColor: 'rgba(0, 0, 0, 0.1)',
                            }
                        },
                        data: itemvaule
                    },
                    {
                        name: 'Proportion',
                        type: 'line',
                        yAxisIndex: 1,
                        data: linevaule,
                        lineStyle: {
                            width: 3
                        },
                        symbolSize: 8,
                        itemStyle: { 
                            borderWidth: 2,
                            normal: { 
                                color: '#00C598 ' 
                            } 
                        },
                        areaStyle: {
                            normal: {
                                color: new echarts.graphic.LinearGradient(0, 0, 0, 1,
                                    [
                                        { offset: 0, color: 'rgba(0, 197, 152, 0.5)' },
                                        { offset: 0.8, color: 'rgba(0, 197, 152, 0.1)' }
                                    ], false),
                                shadowColor: 'rgba(0, 0, 0, 0.1)',
                                shadowBlur: 1
                            }
                        },
                        tooltip: {
                            valueFormatter: function (value) {
                                return value + '%';
                            }
                        }
                    }
                ]
            };
            myChart.setOption(option);
            window.addEventListener('resize', function () {
                myChart.resize();
            });
            /*
            if (plato_optionloop) {
                //plato_optionloop.clearLoop();
                plato_optionloop = null;
            }
            plato_optionloop = tools.loopShowTooltip(echarts.init(chart), option, { loopSeries: true });
            */
        };
    </script>
</body>
</html>
